<template>
    <div class="charts" :id="item.id" ref="myCharts">
        <a-spin :spinning="loadingState">
            <div :id="'myChart' + item.id"></div>
        </a-spin>
    </div>
</template>

<script>
import { mapActions, mapState } from 'vuex'
import China from '@/assets/China.json'
import ElementResize from '@/views/reportForms/show_report/elementResize';
import bus from '@/views/components/bus'
  export default {
    props: ['rowHeight', 'item', 'dataApkdb', 'loadingState'],
    data() {
      return {
        myChart: null,
        option: {},
        chartHeight: 0,
        chartWidth: 0,
        ChinaMap: null,
        funnelConfig: {}
      }
    },
    computed: {
      ...mapState('charts', ['chartList']),
      ...mapState('custom', ['DsList']),
    },
    watch: {},
    methods: {
      ...mapActions('custom', ['getDsList', 'getUpdateReportDs']),
      setFunnelOption () {
        let resultSet = this.dataApkdb[this.item.dataMapping.datasetId];
          if (resultSet && resultSet.length > 0) {
              let seriesData = [];
              let seriesName = "总体";
              let startStepValue = 1;
              let endStepValue = 0;
              let prevStep = null;
              let steps = this.funnelConfig.funnel.steps;
              for (let j = 0; j < steps.length; j++) {
                  let step = steps[j];
                  if (step.order === 1) {
                      startStepValue = resultSet[0][
                          step.event.toLowerCase() + "_" + step.order
                      ];
                  } else if (step.order === steps.length) {
                      endStepValue = resultSet[0][
                          step.event.toLowerCase() + "_" + step.order
                      ];
                  }
                  let rate = 0;
                  if (step.order === 1) {
                      rate = 100;
                  } else if (
                      resultSet[0].hasOwnProperty(
                          prevStep.event.toLowerCase() + "_" + prevStep.order
                      )
                  ) {
                      let a =
                          resultSet[0][step.event.toLowerCase() + "_" + step.order] *
                          100;
                    let b = resultSet[0][
                        prevStep.event.toLowerCase() + "_" + prevStep.order
                    ];

                    if (b == 0) {
                        rate = 0;
                    } else {
                        rate = Math.ceil(a / b);
                    }
                  }
                  seriesData.push({
                    value: resultSet[0][
                      step.event.toLowerCase() + "_" + step.order
                      ],
                      name: step.name,
                      rate: rate
                  });
                  prevStep = step;
              }
              return seriesData
          } else {
            return []
          }
      },
      getFunnelConfig () {
          return new Promise((resolve, reject)=> {
              this.getUpdateReportDs({ id: this.item.dataMapping.datasetId })
                  .then(res => {
                      this.funnelConfig = JSON.parse(res.data.config).config;
                      resolve(this.setFunnelOption());
                  })
                  .catch(err =>{
                      reject(err)
                  })

          })
      },
      getUnit (measureName) {
          let unit = "";
          switch (measureName) {
            case "session_id":
              unit = "会话";
              break;
            case "eship_id":
              unit = "人";
              break;
            default:
              unit = "";
              break;
          }
          return unit;
      },
      initCharts () {
        let _that = this.item
        if (this.myChart) {
          this.myChart.dispose();//销毁
          this.myChart = null;
        }
        try {
          this.chartWidth = this.$refs.myCharts && this.$refs.myCharts.clientWidth
          this.chartHeight = this.$refs.myCharts && this.$refs.myCharts.clientHeight
        } catch (error) {
          console.error(error)
          this.$nextTick(()=>{
            this.chartWidth = this.$refs.myCharts.clientWidth
            this.chartHeight = this.$refs.myCharts.clientHeight
          })          
        }
        this.myChart = this.$echarts.init(document.getElementById('myChart'+this.item.id), 'light', {width: this.chartWidth, height: this.chartHeight})
        let option = {
          grid:{
            top: '5%',
            left: '5%',
            right: '5%',
            bottom: '5%',
            containLabel: true
          },
          legend: {},
          dataset: [],
          tooltip: {
            trigger: 'axis'
          },
          toolbox: {},
          xAxis: {
            type: 'category'
          },
          yAxis: {},
          series: []
        }

        if (_that.type == 'funnel') {
          this.getFunnelConfig().then(res=>{
              option.dataset.push({
                  source: res
              })
              option.series.push({
                type: 'funnel',
                encode: {
                  itemName: "name"
                },
                bottom: 12,
              })
              if (_that.display.label) {
                  option.series[0].label = {..._that.display.label,
                      formatter: params =>{
                          return (
                              params.data.name +
                              "\n" +
                              params.data.value +
                              this.getUnit(this.funnelConfig.funnel.measure.name) +
                              "(" +
                              params.data.rate +
                              "%)"
                          );
                      }
                  }
              }
              if (_that.display.legend && _that.display.legend.show) {
                  option.legend = _that.display.legend
              } else {
                  delete option.legend
              }
              if (_that.display.toolbox && _that.display.toolbox.show) {
                  for(let key in _that.display.toolbox){
                      if(key == 'show'){
                          option.toolbox[key] = _that.display.toolbox[key]
                      } 
                      let feature = _that.display.toolbox[key]
                      if(key == 'feature' && feature.length) {
                          option.toolbox.feature = {}
                          for(let i=0; i<feature.length; i++){
                              if(feature[i] == 'saveAsImage') {
                                  option.toolbox.feature[feature[i]] = {type: 'png'}
                              }
                              if(feature[i] == 'dataView') {
                                  option.toolbox.feature[feature[i]] = {show: true}
                              }
                          }
                      }
                  }
              } else {
                  delete option.toolbox
              }
              delete option.xAxis
              delete option.yAxis
              delete option.tooltip
              delete option.grid
              this.myChart.setOption(option, true);
          })
          return
        }

         // 设置数据集
        let map = {};
        if (_that.type == 'map') {
          this.item.dataMapping.forEach((data, index) => {
            let dataMap = [];
            let dataset = this.dataApkdb[data.datasetId]
            map[data.datasetId] = index;
            dataset && dataset.forEach(item => {
              dataMap.push({
                name: item[data.name],
                value: item[data.value]
              })
            })
            option.dataset.push({source: dataMap})
          })
        } else  {
          this.item.dataMapping.forEach((data, index) => {
            if (this.dataApkdb[data.datasetId]) {
              option.dataset.push({source: this.dataApkdb[data.datasetId]})
              map[data.datasetId] = index;
            }
          })
        }
        this.item.dataMapping.forEach((data) => {
          for (let key in map) {
            if (data.datasetId == key) {
              if (_that.type == 'pie' || _that.type == 'loop') {
                option.series.push({
                  type: 'pie',
                  name: data.name,
                  datasetIndex: map[key],
                  encode: {
                    itemName: data.itemName,
                    value: data.value
                  },
                  radius: _that.display.series[0].radius,
                  emphasis: {}
                })
              } else {
                if (_that.type == 'line' || _that.type == 'area') {
                  if (_that.type == 'line') {
                    option.series.push({
                      type: 'line',
                      datasetIndex: map[key],
                      name: data.name,
                      encode: {
                        x: data.x,
                        y: data.y
                      },
                      emphasis: {}
                    })
                  } else {
                    option.series.push({
                      type: 'line',
                      name: data.name,
                      areaStyle: {},
                      datasetIndex: map[key],
                      encode: {
                        x: data.x,
                        y: data.y
                      },
                      emphasis: {}
                    })
                  }
                } else if(_that.type == 'bar' || _that.type == 'strip') {
                  option.series.push({
                    type: 'bar',
                    name: data.name,
                    datasetIndex: map[key],
                    encode: {
                      x: _that.type == 'bar' ? data.x : data.y,
                      y: _that.type == 'bar' ? data.y : data.x
                    },
                    emphasis: {}
                  })
                } else {
                  if (_that.type == 'map') {
                    option.series.push({
                      type: 'map',
                      mapType: data.mapType,
                      datasetIndex: map[key],
                      zoom: 1.7,
                      nameMap: {
                        '北京市': '北京市',
                        '天津市': '天津市',
                        '河北省': '河北省',
                        '山西省': '山西',
                        '内蒙古自治区': '内蒙古自治区',
                        '辽宁省': '辽宁',
                        '吉林省': '吉林',
                        '黑龙江省': '黑龙江省',
                        '上海市': '上海',
                        '江苏省': '江苏省',
                        '浙江省': '浙江省',
                        '安徽省': '安徽',
                        '福建省': '福建省',
                        '江西省': '江西',
                        '山东省': '山东省',
                        '河南省': '河南',
                        '湖北省': '湖北省',
                        '湖南省': '湖南',
                        '广东省': '广东',
                        '广西壮族自治区': '广西壮族自治区',
                        '海南省': '海南',
                        '重庆市': '重庆',
                        '四川省': '四川省',
                        '贵州省': '贵州',
                        '云南省': '云南',
                        '西藏自治区': '西藏自治区',
                        '陕西省': '陕西',
                        '甘肃省': '甘肃',
                        '青海省': '青海省',
                        '宁夏回族自治区': '宁夏回族自治区',
                        '新疆维吾尔自治区': '新疆'
                      }
                    })
                  } else {
                    if (_that.type == 'group') {
                      option.series.push({
                        type: 'line',
                        name: data.name,
                        datasetIndex: map[key],
                        encode: {
                          x: data.x,
                          y: data.y
                        },
                        emphasis: {}
                      })
                      option.series.push({
                        type: 'bar',
                        name: data.name,
                        datasetIndex: map[key],
                        encode: {
                          x: data.x,
                          y: data.y
                        },
                        emphasis: {}
                      })
                    } else { 
                      option.series.push({
                        type: _that.type,
                        name: data.name,
                        datasetIndex: map[key],
                        encode: {
                          x: data.x,
                          y: data.y
                        },
                        emphasis: {}
                      })
                    }
                  }
                }
                
              }
            }
          }
        })

        if (_that.type == 'strip') {
          option.xAxis.type = 'value'
          option.yAxis.type = 'category'
        } else if (_that.type == 'pie' || _that.type == 'loop') {
          option.tooltip = {
            trigger: 'item',
          }
          delete option.xAxis
          delete option.yAxis
        }


        let datasetList = this.DsList.map(data => {
          return {...data, output: JSON.parse(data.output)}
        })

        option.series.forEach((item, index) => {
          datasetList.forEach(data => {
            for(let key in map) {
              if (map[key] == item.datasetIndex) {
                if (key == data.id) {
                  let out = data.output
                  for(let i=0; i<out.length; i++) {
                    if (item.type != 'map') {
                      if (item.type == 'bar' && option.xAxis.type == 'value' && option.yAxis.type == 'category') {
                        if (out[i].name == item.encode.x) {
                          option.series[index].name = out[i].displayName
                        }
                      } else {
                        if (out[i].name == item.encode.y) {
                          option.series[index].name = out[i].displayName
                        }
                      }
                    }
                  }
                }
              }
            }
          })
        })

        if (_that.display.roam) {
          option.roam = true
        }

        // 高亮显示
        // 聚焦效果
        if(_that.display.emphasis && _that.display.emphasis.focus){
          for (let i = 0; i < option.series.length; i++) {
            option.series[i].emphasis.focus = _that.display.emphasis.focus
          }
        }
        // 放大效果
        if(_that.display.emphasis && _that.display.emphasis.scale){
          for (let i = 0; i < option.series.length; i++) {
            option.series[i].emphasis.scale =  _that.display.emphasis.scale
          }
        }
        // 线条样式
        if (_that.display.lineStyle) {
          for (let i = 0; i < option.series.length; i++) {
            option.series[i].lineStyle = _that.display.lineStyle
          }
        }
        // 线条平滑处理
        if (_that.display.smooth) {
          for (let i = 0; i < option.series.length; i++) {
            option.series[i].smooth = _that.display.smooth
          }
        }
        // 目标线
        if (_that.display.markLine&&_that.display.markLine.show) {
          for (let i = 0; i < option.series.length; i++) {
            option.series[i].markLine = {data: _that.display.markLine.data}
            option.series[i].markLine.label = { position: 'middle' }
          }
        }
        // 图形上的文本标签
        if (_that.display.label) {
          for (let i = 0; i < option.series.length; i++) {
            option.series[i].label = _that.display.label
          }
        }

        // 设置工具箱
        if (_that.display.toolbox) {
          for(let key in _that.display.toolbox){
            if(key == 'show'){
              option.toolbox[key] = _that.display.toolbox[key]
            } 
            let feature = _that.display.toolbox[key]
            if(key == 'feature' && feature.length) {
              option.toolbox.feature = {}
              for(let i=0; i<feature.length; i++){
                if(feature[i] == 'saveAsImage') {
                  option.toolbox.feature[feature[i]] = {type: 'png'}
                }
                if(feature[i] == 'dataView') {
                  option.toolbox.feature[feature[i]] = {show: true}
                }
              }
            }
          }
        }

        // 设置图例
        if (_that.display.legend && _that.display.legend.show) {
          option.grid.top = '16%'
          option.legend = _that.display.legend
        } else {
          delete option.legend
        }

        if (_that.type == 'map') {
          this.$echarts.registerMap('China', China)
          delete option.xAxis
          delete option.yAxis
          delete option.legend
          option.tooltip = {
            trigger: 'item',
          }
          option.center = [110, 36]
          option.visualMap = {
            ..._that.display.visualMap,
            min: Number(_that.display.visualMap.min),
            max: Number(_that.display.visualMap.max)
          }
        }
        // 绘制图表
        this.myChart.setOption(option, true);
      },
    },
    mounted() {
      window.addEventListener('resize', this.initCharts)
      this.initCharts();
      ElementResize.on(document.getElementById(this.item.id), () => {
        this.$nextTick(() => {
          this.initCharts();
        });
      });
    },
    beforeDestroy() {
      window.removeEventListener('resize', this.initCharts);
      if (this.myChart) {
        this.myChart.dispose();//销毁
        this.myChart = null;
      }
    },
  }
</script>

<style scoped>
.charts {
  width: 100%;
  height: calc(100% - 70px);
}

.ant-spin-nested-loading {
  height: calc(100% - 70px);
}

.ant-spin-nested-loading>>>.ant-spin-container {
  height: calc(100% - 70px);
}
</style>
